package com.atguigu.tingshu.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.atguigu.tingshu.common.constant.RedisConstant;
import com.atguigu.tingshu.common.rabbit.constant.MqConst;
import com.atguigu.tingshu.common.rabbit.service.RabbitService;
import com.atguigu.tingshu.model.user.UserInfo;
import com.atguigu.tingshu.model.user.UserPaidAlbum;
import com.atguigu.tingshu.model.user.UserPaidTrack;
import com.atguigu.tingshu.user.mapper.UserInfoMapper;
import com.atguigu.tingshu.user.mapper.UserPaidAlbumMapper;
import com.atguigu.tingshu.user.mapper.UserPaidTrackMapper;
import com.atguigu.tingshu.user.service.UserInfoService;
import com.atguigu.tingshu.vo.user.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

	@Autowired
	private UserInfoMapper userInfoMapper;

	@Autowired
	private WxMaService wxMaService;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RabbitService rabbitService;

	@Autowired
	private UserPaidAlbumMapper userPaidAlbumMapper;

	@Autowired
	private UserPaidTrackMapper userPaidTrackMapper;

	@Override
	public UserInfoVo getUserInfo(Long userId) {
		//	查询数据
		UserInfo userInfo = this.getById(userId);
		//	属性拷贝：
		UserInfoVo userInfoVo = new UserInfoVo();
		BeanUtils.copyProperties(userInfo,userInfoVo);
		//	返回数据
		return userInfoVo;
	}

	@Override
	public void updateUserInfo(UserInfoVo userInfoVo, Long userId) {
		//	创建对象
		UserInfo userInfo = new UserInfo();
		//	属性拷贝：
		BeanUtils.copyProperties(userInfoVo,userInfo);
		userInfo.setId(userId);
		//	更新用户信息
		userInfoMapper.updateById(userInfo);
	}

	@Override
	public Map<String, Object> wxLogin(String code) {
		//	声明一个map 集合
		Map<String, Object> map = new HashMap<>();

		WxMaJscode2SessionResult wxMaJscode2SessionResult = null;
		try {
			wxMaJscode2SessionResult = wxMaService.jsCode2SessionInfo(code);
		} catch (WxErrorException e) {
			throw new RuntimeException(e);
		}
		//	获取到微信用户对应的微信标识
		String openid = wxMaJscode2SessionResult.getOpenid();
		//	通过这个openid 查询用户信息，如果有对应的信息记录，则说明用户已经注册过
		//	如果没有，则说明用户未注册过，实现注册功能，并初始化账户金额, 留住用户
		UserInfo userInfo = userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getWxOpenId, openid));
		//	判断用户信息是否存在
		if ( null == userInfo){
			//	第一次注册;
			//	发送消息实现初始化账户信息；
			userInfo = new UserInfo();
			userInfo.setWxOpenId(openid);
			userInfo.setNickname("用户" + UUID.randomUUID().toString().replaceAll("-", ""));
			userInfo.setAvatarUrl("https://oss.aliyuncs.com/aliyun_id_photo_bucket/default_handsome.jpg");
			//	添加到表中
			userInfoMapper.insert(userInfo);
			//	发送一个消息，账户金额初始化
			rabbitService.sendMessage(MqConst.EXCHANGE_USER, MqConst.ROUTING_USER_REGISTER, userInfo.getId());
		}
		//	直接存储到缓存，并返回一个token
		String token = UUID.randomUUID().toString().replaceAll("-", "");
		//	缓存key
		String userLoginKey = RedisConstant.USER_LOGIN_KEY_PREFIX + token;
		//	获取到当前服务器的Ip 地址：   userInfo+ip;
		redisTemplate.opsForValue().set(userLoginKey,userInfo,RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
		//	存储数据
		map.put("token",token);
		//	返回数据
		return map;
	}

	/**
	 *  判断用户是否购买了声音
	 * @param albumId 专辑Id
	 * @param trackIdList 付费声音Id 列表; 6-25;
	 * @param userId 用户Id
	 * @return
	 */
	@Override
	public Map<Long, Integer> userIsPaidTrack(Long albumId, List<Long> trackIdList, Long userId) {
		//	创建map 集合
		Map<Long, Integer> map = new HashMap<>();
		//	判断用户是否购买专辑： user_paid_album;
		UserPaidAlbum userPaidAlbum = userPaidAlbumMapper.selectOne(new LambdaQueryWrapper<UserPaidAlbum>().eq(UserPaidAlbum::getUserId, userId).eq(UserPaidAlbum::getAlbumId, albumId));
		//	判断
		if ( null != userPaidAlbum){
			//	这个用户购买过专辑 map.put(trackId,1); map.put(trackId,0); 1:表示已经购买; 0:表示未购买 setIsShowPaidMark(true);
			return trackIdList.stream().collect(Collectors.toMap(trackId -> trackId, trackId -> 1));
		} else {
			//	判断用户是否购买声音： user_paid_track;
			//	构建查询条件;
			LambdaQueryWrapper<UserPaidTrack> wrapper = new LambdaQueryWrapper<>();
			wrapper.eq(UserPaidTrack::getUserId,userId).in(UserPaidTrack::getTrackId,trackIdList).eq(UserPaidTrack::getAlbumId,albumId);
			//	查询到的结果是：这个用户购买过哪些声音 userPaidTrackList 这个集合可能为空：说明用户未购买过任何一条声音;
			//	19,20;
			List<Long> userPaidTrackIdList = userPaidTrackMapper.selectList(wrapper).stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
			//	List<Long> userPaidTrackIdList;
			//	判断：
			for (Long trackId : trackIdList) {
				//	判断购买声音Id 的集合中是否包含付费声音Id
				if (userPaidTrackIdList.contains(trackId)){
					//	购买过
					map.put(trackId,1);
				} else {
					//	未购买过
					map.put(trackId,0);
				}
			}
		}
		//	返回集合;
		return map;
	}
}
